Support Windows shell virtual files in drag and drop - #21907
Conversation
|
You can test this PR using the following package version. |
|
You can test this PR using the following package version. |
There was a problem hiding this comment.
Pull request overview
This PR adds Windows shell virtual-file support to Avalonia’s Win32 OLE data-transfer backend, enabling drag-and-drop of files that don’t yet have filesystem paths (e.g., items dragged out of ZIP folders in Windows Explorer) by exposing them through the existing DataFormat.File / IStorageFile APIs.
Changes:
- Add
OleVirtualFileDatato parseFileGroupDescriptorWand fetch indexedFileContentsasIStorageFileinstances, including COM apartment-safe marshaling forIStream. - Extend
OleDataObjectToDataTransferWrapperto surface virtual files asDataFormat.Fileand avoid duplicating file formats in the non-file transfer item. - Add Win32 integration tests and grant test assembly access via
InternalsVisibleTo; addIDataObjectAsyncCapabilityto Win32 COM IDL.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Avalonia.IntegrationTests.Win32/OleVirtualFileDataTests.cs | Adds integration tests for descriptor parsing, virtual file exposure, and async operation completion. |
| src/Windows/Avalonia.Win32/Win32Com/win32.idl | Introduces IDataObjectAsyncCapability COM interface definition for async drag/drop lifetime management. |
| src/Windows/Avalonia.Win32/OleVirtualFileData.cs | Implements virtual-file parsing, FileContents extraction (IStream/HGLOBAL), and async operation lifetime handling. |
| src/Windows/Avalonia.Win32/OleDataObjectToDataTransferWrapper.cs | Detects virtual-file formats and materializes them as DataFormat.File items without duplicating formats in non-file items. |
| src/Windows/Avalonia.Win32/Avalonia.Win32.csproj | Adds InternalsVisibleTo for the Win32 integration test assembly. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
You can test this PR using the following package version. |
|
You can test this PR using the following package version. |
|
@MrJul Thank you for the review. I addressed the requested changes in 15ff497:
I also merged the latest main. Avalonia.IntegrationTests.Win32 passes 242/242, the net8/net10 Release builds succeed, and a rooted win-x64 NativeAOT smoke publish plus executable run succeed. Could you please take another look? |
|
You can test this PR using the following package version. |
|
Follow-up for the latest review (commit dc7c913):
Validation after these changes: net8.0/net10.0 Release builds succeeded, Avalonia.IntegrationTests.Win32 passed 242/242, and the rooted win-x64 NativeAOT smoke publish and executable run succeeded. Please re-review when the CI checks finish. |
|
You can test this PR using the following package version. |
MrJul
left a comment
There was a problem hiding this comment.
Last round of review with a few remaining nits, this PR is looking great!
|
Addressed the five remaining review comments in 72ba8a7:
Validation on Windows:
All review threads are resolved. Please re-review when the CI checks complete. |
|
You can test this PR using the following package version. |
MrJul
left a comment
There was a problem hiding this comment.
Tested against Explorer's zip handler and Outlook's attachments, with both drag-and-drop and clipboard. It works as expected.
LGTM!
|
You can test this PR using the following package version. |
What does the pull request do?
Adds Windows shell virtual-file support to the OLE data-transfer backend. Applications can now receive files dragged from sources that do not expose a filesystem path yet, including entries dragged from ZIP folders in Windows Explorer.
Virtual entries are exposed through the existing
DataFormat.File/IStorageFileAPI, so no new public API is required.What is the current behavior?
OleDataObjectToDataTransferWrapperonly recognizes physical files supplied throughCF_HDROP. A Windows shell source that suppliesFileGroupDescriptorWplus indexedFileContentstherefore does not produceDataFormat.Fileitems.What is the updated/expected behavior with this PR?
FileGroupDescriptorWandFileContentsare recognized as file data.IStorageFile, including its name and optional size.FileContentssupports bothIStreamandHGLOBALproviders.IDataObjectAsyncCapabilitykeeps the source operation alive afterDropreturns and is completed when all returned storage items are disposed.How was the solution implemented (if it's not obvious)?
The Win32 backend parses the shell
FILEGROUPDESCRIPTORWpayload and requests each indexedFileContentsentry. COMIStreamandIDataObjectAsyncCapabilityinterfaces are explicitly marshaled between apartments. The unmarshaled stream is owned by a generated MicroCom proxy, retaining trimming and NativeAOT compatibility while also providing finalizer-backed COM lifetime management.IStream.Readpreserves the raw HRESULT so the documentedS_FALSEend-of-stream result is handled correctly, andLength/Seek/Positiondelegate to the underlying stream.The implementation requests
TYMED_ISTREAMfirst and retries withTYMED_HGLOBAL, because some validIDataObjectimplementations provide only the latter.The non-file transfer item now receives only its actual non-file formats, preventing a duplicate
DataFormat.Fileitem when virtual files are present. A failure to materialize one virtual file is logged as a warning and does not prevent the remaining files from being returned.Validation performed:
Avalonia.Win32Release builds fornet8.0andnet10.0: succeeded.Avalonia.IntegrationTests.Win32: 242 passed, including virtual-file contents/size, truncated descriptor input, and completingIDataObjectAsyncCapabilityfrom a worker thread.win-x64NativeAOT smoke publish withOleVirtualFileDatarooted: succeeded, and the generated executable ran successfully. The root-all harness surfaces an existingEnum.GetValues(Type)IL3050 warning outside this implementation.Checklist
Breaking changes
None.
Obsoletions / Deprecations
None.
Fixed issues
None.